home *** CD-ROM | disk | FTP | other *** search
- /* ScianFontSystem.c
- Routines for font system and string utilities
-
- Jim Lyons
- 7/26/91
-
- 9/24/91 added support for raster fonts
- 1/5/92 EMP added font counting for both types of fonts
- 1/28/92 modified StrWidth and DrawString to handle tabs
- 4/6/92 added PostScript drawing mode
- 9/14/92 changed DrawString to take alignment parameter
- and changed name to DrawAString
- 9/10/93 added SetUIFont
- */
-
- #include "Scian.h"
- #include "ScianStyle.h"
- #include "ScianTypes.h"
- #include "ScianFontSystem.h"
- #include "ScianWindows.h"
- #include "ScianDraw.h"
- #include "ScianTextBoxes.h"
-
- #ifdef GRAPHICS
- #include "ScianPalatino18.h"
- #include "ScianTitleFont.h"
-
- #define NRASTERFONTS 4 /* NOT including system font or icon fonts */
- #define SCIANTITLE 1
- #define MAXFONTSUSED 10 /* max different fonts in window (for PS drawing) */
-
- #endif
-
- #ifndef TABWID
- #define TABWID 4 /* number of 'chars' per tab stop */
- #endif
-
- /*
- The font system handles font manager routines, if available, as
- well as raster fonts. When SetupFont is called, the font name
- is first looked up using fmfindfont. If found, the font is scaled
- to size and currentFontHandle is set for use by subsequent calls
- to DrawAString, StringWidth, etc. If fmfindfont fails (or if not
- FONTS4D) currentFontHandle is set to NULL and the name is looked
- up in the raster font name table, rasterFont[]. (The size parameter
- is ignored.) If not found the system font is used.
-
- Note that icon fonts are not treated like text fonts, although they
- are initialized here in InitFonts.
- */
-
- /* globals for font system */
-
- #ifdef GRAPHICS
-
- char *rasterFont[NRASTERFONTS + 1]; /* table of raster font name pointers */
- int nFonts = 0;
- char **fonts;
- static int registeredFonts;
- char curFontName[64]; /* remember which font is set */
- int curFontSize;
-
- #ifdef FONTS4D
- fmfonthandle currentFontHandle = NIL;
- #endif
-
- struct fontinfo uiFontInfo[NUIFONTS] =
- {
- "Helvetica-BoldOblique", 12, 0,
- "Helvetica", 10, 0,
- "Helvetica", 12, 0,
- "Helvetica", 14, 0,
- "Helvetica", 18, 0,
- "Helvetica-Bold", 10, 0,
- "Helvetica-Bold", 12, 0,
- "Helvetica-Bold", 14, 0,
- "Helvetica-Bold", 18, 0
- };
-
- #endif
-
- char *fontsUsed[MAXFONTSUSED]; /* list of fonts used in PostScript file */
- int numFontsUsed = 0; /* number of fonts used = next index */
- char showBuf[256]; /* string buffer for PostScript show */
-
-
- static void CountFonts(s)
- char *s;
- /*Counts the fonts*/
- {
- #ifdef GRAPHICS
- ++nFonts;
- #endif
- }
-
- static void RegisterFont(s)
- char *s;
- /*Puts the font names in a list, fonts[]*/
- {
- #ifdef GRAPHICS
- fonts[registeredFonts] = Alloc(strlen(s) + 1);
- strcpy(fonts[registeredFonts], s);
- ++registeredFonts;
- #endif
- }
-
- #ifdef PROTO
- static int CompareFonts(const void *f1, const void *f2)
- #else
- static int CompareFonts(f1, f2)
- void *f1;
- void *f2;
- #endif
- /*Compares two font names*/
- {
- return strcmp2(*(char **) f1, *(char **) f2);
- }
-
- #ifdef PROTO
- static void SortFonts(void)
- #else
- static void SortFonts()
- #endif
- {
- /*Sorts the fonts*/
-
- qsort(fonts, registeredFonts, sizeof(char *), CompareFonts);
- }
-
- void InitFonts(void) /*********************************** INITFONTS */
- {
- #ifdef GRAPHICS
- int i;
- #ifdef FONTS4D
- fmfonthandle fh;
- #endif
-
- nFonts = 2;
-
- #ifdef FONTS4D
- fminit();
- fmenumerate(CountFonts);
- #endif
- fonts = (char**) Alloc(sizeof(char *) * nFonts);
- #ifdef FONTS4D
- /* register fonts for font menu */
- registeredFonts = 0;
- fmenumerate(RegisterFont);
- #endif
-
- /*Complete font menu with System and Palatino18*/
- RegisterFont("System");
- RegisterFont("Palatino18");
-
- SortFonts();
-
- rasterFont[0] = "System"; /* default */
- for (i=1; i<NRASTERFONTS+1; ++i) rasterFont[i] = "\0";
-
- #ifdef BIGFONTSOK
- rasterFont[TITLEFONT] = "ScianTitle";
- defrasterfont(TITLEFONT, ScianTitleFontHT, ScianTitleFontNC, ScianTitleFontchars,
- ScianTitleFontRS, (void *) ScianTitleFontrasters);
- #endif
- rasterFont[SUBTITLEFONT] = "Palatino18";
- defrasterfont(SUBTITLEFONT, palatino18HT, palatino18NC, stChars,
- palatino18RS, (void *) stRasters);
-
- numFontsUsed = 0;
- strcpy(curFontName, "System");
- curFontSize = 10;
-
- #ifdef FONTS4D
- /* set up fonts for user interface */
- /* Regular fonts */
- fh = fmfindfont(uiFontInfo[UISMALLFONT].name);
- if (fh)
- {
- uiFontInfo[UISMALLFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UISMALLFONT].size);
- uiFontInfo[UINORMALFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UINORMALFONT].size);
- uiFontInfo[UILARGEFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UILARGEFONT].size);
- uiFontInfo[UITITLEFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UITITLEFONT].size);
- }
- /* Bold fonts */
- fh = fmfindfont(uiFontInfo[UIBOLDSMALLFONT].name);
- if (fh)
- {
- uiFontInfo[UIBOLDSMALLFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UIBOLDSMALLFONT].size);
- uiFontInfo[UIBOLDNORMALFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UIBOLDNORMALFONT].size);
- uiFontInfo[UIBOLDLARGEFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UIBOLDLARGEFONT].size);
- uiFontInfo[UIBOLDTITLEFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UIBOLDTITLEFONT].size);
- }
- else
- {
- uiFontInfo[UIBOLDSMALLFONT].fontHandle =
- uiFontInfo[UISMALLFONT].fontHandle;
- uiFontInfo[UIBOLDNORMALFONT].fontHandle =
- uiFontInfo[UINORMALFONT].fontHandle;
- uiFontInfo[UIBOLDLARGEFONT].fontHandle =
- uiFontInfo[UILARGEFONT].fontHandle;
- uiFontInfo[UIBOLDTITLEFONT].fontHandle =
- uiFontInfo[UITITLEFONT].fontHandle;
- }
- /* menu font */
- fh = fmfindfont(uiFontInfo[UIMENUFONT].name);
- if (fh)
- {
- uiFontInfo[UIMENUFONT].fontHandle = (char **)
- fmscalefont(fh, uiFontInfo[UIMENUFONT].size);
- }
- else
- {
- if (uiFontInfo[UIBOLDNORMALFONT].fontHandle)
- uiFontInfo[UIMENUFONT].fontHandle =
- uiFontInfo[UIBOLDNORMALFONT].fontHandle;
- else uiFontInfo[UIMENUFONT].fontHandle =
- uiFontInfo[UINORMALFONT].fontHandle;
- }
- #endif
-
- #endif
- }
-
- void KillFonts(void)
- {
- #ifdef GRAPHICS
- int k;
- /*** free memory ***/
- for (k = 0; k < nFonts; ++k)
- {
- Free(fonts[k]);
- }
- if (fonts)
- {
- Free(fonts);
- }
- #endif
- }
-
- #ifdef PROTO
- Bool SetupFont(char *name, int size)
- #else
- Bool SetupFont(name, size)
- char *name;
- int size;
- #endif
- {
- #ifdef GRAPHICS
- int i;
-
- if (drawingMode == DRAW_SCREEN)
- {
- #ifdef FONTS4D
- currentFontHandle = fmfindfont(name);
- if (currentFontHandle)
- {
- currentFontHandle = fmscalefont(currentFontHandle, size);
- fmsetfont(currentFontHandle);
- return true;
- }
- else
- {
- currentFontHandle = NIL;
- for (i=1; i<NRASTERFONTS+1; ++i)
- {
- if (strcmp(name, rasterFont[i]) != 0) continue;
- font(i);
- return true;
- }
- font(0);
- return false;
- }
- #else
- for (i=1; i<NRASTERFONTS+1; ++i)
- {
- if (strcmp(name, rasterFont[i]) != 0) continue;
- font(i);
- return true;
- }
- font(0);
- return false;
- #endif
- }
- else if (drawingMode == DRAW_POSTSCRIPT && psFile)
- {
- /* see if same as current font and size */
- if (strcmp(name, curFontName) == 0 && size == curFontSize) return true;
- RegisterFontUsed(name); /* add to list for PS file trailer */
- strcpy(curFontName, name); /* remember this */
- curFontSize = size;
-
- /* write PostScript to drawing file to set up font */
- /* size is made larger by 2 points to adjust for screen vs printer */
- fprintf(psFile, "/%s findfont %d scalefont setfont\n", name, size+2);
- return true;
- }
- #endif
- return false;
- }
-
- #ifdef PROTO
- void SetUIFont(int uiFontNum)
- #else
- void SetUIFont(uiFontNum)
- int uiFontNum;
- #endif
- {
- #ifdef GRAPHICS
- if (drawingMode == DRAW_SCREEN)
- {
- #ifdef FONTS4D
- currentFontHandle = (fmfonthandle) uiFontInfo[uiFontNum].fontHandle;
- fmsetfont(currentFontHandle);
- #else
- font(0);
- #endif
- }
- else if (drawingMode == DRAW_POSTSCRIPT && psFile)
- {
- /* see if same as current font and size */
- if (strcmp(uiFontInfo[uiFontNum].name, curFontName) == 0
- && uiFontInfo[uiFontNum].size == curFontSize) return;
- RegisterFontUsed(uiFontInfo[uiFontNum].name);
- strcpy(curFontName, uiFontInfo[uiFontNum].name); /* remember this */
- curFontSize = uiFontInfo[uiFontNum].size;
-
- /* write PostScript to drawing file to set up font */
- /* size is made larger by 2 points to adjust for screen vs printer */
- fprintf(psFile, "/%s findfont %d scalefont setfont\n",
- uiFontInfo[uiFontNum].name, uiFontInfo[uiFontNum].size+2);
- }
- #endif
- }
-
- #ifdef PROTO
- void RegisterFontUsed(char *name)
- #else
- void RegisterFontUsed(name)
- char *name;
- #endif
- {
- /* for PostScript file output--makes list of fonts used for trailer */
- #ifdef GRAPHICS
- int i;
-
- /* check list of fonts used */
- for (i = 0; i < numFontsUsed; ++i)
- {
- if (strcmp(name, fontsUsed[i]) == 0) return;
- }
- if (numFontsUsed >= MAXFONTSUSED)
- {
- ReportError("RegisterFontUsed","Too many fonts!");
- return;
- }
- fontsUsed[numFontsUsed] = Alloc(strlen(name) + 1);
- if (fontsUsed[numFontsUsed])
- {
- strcpy(fontsUsed[numFontsUsed], name);
- ++numFontsUsed;
- }
- else OMErr();
- #endif
- return;
- }
-
-
- #ifdef PROTO
- int ChrWidth(char c)
- #else
- int ChrWidth(c)
- char c;
- #endif
- {
- #ifdef GRAPHICS
- if (c < ' ') return 0;
- #ifdef FONTS4D
- if (currentFontHandle)
- {
- return fmgetchrwidth(currentFontHandle, c);
- }
- else
- {
- char buf[2];
-
- buf[0] = c;
- buf[1] = '\0';
- return strwidth(buf);
- }
- #else
- { char buf[2];
-
- buf[0] = c;
- buf[1] = '\0';
- return strwidth(buf);
- }
- #endif
- #else
- return 0;
- #endif
- }
-
- #ifdef PROTO
- int StrWidth(char *s)
- #else
- int StrWidth(s)
- char *s;
- #endif
- /* handles tabs in string */
- {
- #ifdef GRAPHICS
- int nTabs=0;
- char *t=s;
-
- while (*t)
- {
- if (*t++ == '\t')
- {
- s = t; /* point to char following tab */
- ++nTabs; /* incr tab count */
- }
- }
- /* now return the indent plus the length of the string following last tab */
- #ifdef FONTS4D
- if (currentFontHandle)
- {
- return nTabs*TABWID*ChrWidth('0') + fmgetstrwidth(currentFontHandle, s);
- }
- else
- {
- return nTabs*TABWID*ChrWidth('0') + strwidth(s);
- }
- #else
- return nTabs*TABWID*ChrWidth('0') + strwidth(s);
- #endif
- #else
- return 0;
- #endif
- }
-
- #ifdef PROTO
- char *show(char *s)
- #else
- char *show(s)
- char *s;
- #endif
- {
- /*
- * Process any special characters in string for PostScript show.
- */
-
- char *p = showBuf;
-
- while (*s)
- {
- if (*s == '(' || *s == ')' || *s == '\\') *p++ = '\\';
- *p++ = *s++;
- }
- *p = '\0';
- return showBuf;
- }
-
- #ifdef PROTO
- void DrawAString(int align, long x, long y, char *s)
- #else
- void DrawAString(align, x, y, s)
- int align;
- long x, y;
- char *s;
- #endif
- {
- #ifdef GRAPHICS
- int left, right, bottom, top;
- int xx, yy, dxx, dyy;
-
- if (drawingMode == DRAW_SCREEN)
- {
- /* find starting point of string */
- switch (align)
- {
- case RIGHTALIGN:
- x -= StrWidth(s);
- break;
-
- case CENTERALIGN:
- x -= StrWidth(s)/2;
- break;
-
- case LEFTALIGN:
- default:
- break;
- }
-
- /* check to see if string starts out of window */
- GetWindowBounds(&left, &right, &bottom, &top);
- CurOffset(&xx, &yy);
- GetWindowOrigin(&dxx, &dyy);
- left -= xx - dxx;
-
- /* trim string if necessary */
- while (x < left)
- {
- if (*s == '\0') return;
- x += ChrWidth(*s++);
- }
- cmov2i(x, y);
-
- #ifdef FONTS4D
- if (currentFontHandle)
- {
- fmprstr(s);
- }
- else
- {
- charstr(s);
- }
- #else
- charstr(s);
- #endif
- }
- else if (drawingMode == DRAW_POSTSCRIPT && psFile && *s != '\0')
- {
- /* write PostScript to file */
- fprintf(psFile, "%f setgray\n", PSColor());
- switch (align)
- {
- case RIGHTALIGN:
- fprintf(psFile,
- "(%s) dup %d exch stringwidth pop sub %d moveto show\n", show(s), x, y);
- break;
-
- case CENTERALIGN:
- fprintf(psFile,
- "(%s) dup %d exch stringwidth pop 2 div sub %d moveto show\n", show(s), x, y);
- break;
-
- case LEFTALIGN:
- default:
- fprintf(psFile, "%d %d moveto (%s) show\n", x, y, show(s));
- break;
- }
- }
- #endif
- }
-